跳到主要内容

创建型模式-建造者模式

建造者模式是什么?

角色类别说明
Builder接口或抽象类抽象的建造者(它内涵了各个步骤所用的零件)
ConcreateBuilder具体的建造者可以有多个(因为每个建造所用到的零件不同)
Product普通的类具体的产品
Director导演也叫指挥者统一指挥建造者去建造目标(用来存放建造的步骤)

建造者模式就是将构建零件(builder)和组装零件(director)两个操作分离开了

classDiagram Director o-- Builder Builder <|-- ConcreateBuilderA Builder <|-- ConcreateBuilderB ConcreateBuilderA ..> ProductA ConcreateBuilderB ..> ProductB Builder : <<interface>> Builder : +buildPartA() Builder : +buildPartB() Builder : +buildPartC() Builder : +getResult() ConcreateBuilderA : +buildPartA() ConcreateBuilderA : +buildPartB() ConcreateBuilderA : +buildPartC() ConcreateBuilderA : +getResult() ConcreateBuilderB : +buildPartA() ConcreateBuilderB : +buildPartB() ConcreateBuilderB : +buildPartC() ConcreateBuilderB : +getResult()

使用场景:建造模式适用于一个具有较多零件的复杂产品的创建过程,由于需求会经常变更,组成这个复杂产品的各个零件经常变化,但是它们的 组合方式却相对稳定

组装电脑的例子

被建造的对象

创建被建造的对象电脑 --- Computer.java

/**
* Created by TigerChain
* 产品类--被建造的对象
*/
public class Computer {
private String cpu ; // cpu
private String hardDisk ; //硬盘
private String mainBoard ; // 主板
private String memory ; // 内存
... 省略 getter 和 setter
}

抽象的建造者

抽象的建造者 --- Builder.java

/**
* Created by TigerChain
* 抽象的建造者,即装电脑的步骤
* 至于安装什么型号的主板,不是我关心,而是具体的建造者关心的
*/
public interface Builder {
// 安装主板
void createMainBoard(String mainBoard) ;
// 安装 cpu
void createCpu(String cpu) ;
// 安装硬盘
void createhardDisk(String hardDisk) ;
// 安装内存
void createMemory(String memory) ;
// 组成电脑
Computer createComputer() ;
}

具体建造者

具体建造者 --- AssemblerBuilder.java

/**
* Created by TigerChain
* 具体的建造者
*/
public class AssemblerBuilder implements Builder {

private Computer computer = new Computer() ;
@Override
public void createCpu(String cpu) {
computer.setCpu(cpu);
}

@Override
public void createhardDisk(String hardDisk) {
computer.setHardDisk(hardDisk);
}

@Override
public void createMainBoard(String mainBoard) {
computer.setMainBoard(mainBoard);
}

@Override
public void createMemory(String memory) {
computer.setMemory(memory);
}

@Override
public Computer createComputer() {
return computer;
}
}

指挥者:组装步骤

安排装机工工作 --- Director.java

/**
* Created by TigerChain
* 声明一个导演类,用来指挥组装过程,也就是组装电脑的流程
*/
public class Director {
private Builder builder ;

public Director(Builder builder){
this.builder = builder ;
}

public Computer createComputer(String cpu,String hardDisk,String mainBoard,String memory){
// 调用 Builder 里面内涵部件按顺序构建
this.builder.createMainBoard(mainBoard);
this.builder.createCpu(cpu) ;
this.builder.createMemory(memory);
this.builder.createhardDisk(hardDisk);
return this.builder.createComputer() ;
}
}

测试类

/**
* Created by TigerChain
* 测试类
*/
public class Test {
public static void main(String args[]){
Builder builder = new AssemblerBuilder();
Director director = new Director(builder);
Computer computer = director.createComputer(
"Intel 酷睿i9 7900X",
"三星M9T 2TB (HN-M201RAD)",
"技嘉 Z270X-Gaming 7",
"科赋 16GB DDR4 3000");

System.out.println(
"小明这台电脑使用的是:\n" +
computer.getMainBoard() + "主板\n" +
computer.getCpu()+ "CPU\n" +
computer.getHardDisk() + "硬盘\n" +
computer.getMainBoard()+ " 内存\n");

}
}

建造模式构建实体类

以组装电脑为例子,有些参是一些可选项,那么建造者模式可以解决多参数构造方法来建造对象

/**
* Created by TigerChain
* 替代多参构造方法--建造者模式
*/
public class ComputerB {

private String mainBoard ; // 主板
private String cpu ; // cpu
private String hd ; // 硬盘
private String powerSupplier ; // 电源
private String graphicsCard; // 显卡

// 其它一些可选配置
private String mouse ; // 鼠标
private String computerCase ; //机箱
private String mousePad ; //鼠标垫
private String other ; //其它配件

// ComputerB 自己充当 Director
private ComputerB(ComputerBuilder builder) {
this.mainBoard = builder.mainBoard ;
this.cpu = builder.cpu ;
this.hd = builder.hd ;
this.powerSupplier = builder.powerSupplier ;
this.graphicsCard = builder.graphicsCard ;

this.mouse = builder.mouse ;
this.computerCase = builder.computerCase ;
this.mousePad = builder.mousePad ;
this.other = builder.other ;
}
// 声明一个静态内存类 Builder
public static class ComputerBuilder{
// 一个电脑的必须配置
private String mainBoard ; // 主板
private String cpu ; // cpu
private String hd ; // 硬盘
private String powerSupplier ; // 电源
private String graphicsCard; // 显卡

// 其它一些可选配置
private String mouse ; // 鼠标
private String computerCase ; //机箱
private String mousePad ; //鼠标垫
private String other ; //其它配件

// 这里声明一些必须要传的参数「规定这些参数是必须传的,这里只是举例,再实中可能参数都是可选的」
public ComputerBuilder(String mainBoard,String cpu,String hd,String powerSupplier,String graphicsCard){
this.mainBoard = mainBoard ;
this.cpu = cpu ;
this.hd = hd ;
this.powerSupplier = powerSupplier ;
this.graphicsCard = graphicsCard ;
}

public ComputerBuilder setMainBoard(String mainBoard) {
this.mainBoard = mainBoard;
return this ;
}

public ComputerBuilder setCpu(String cpu) {
this.cpu = cpu;
return this ;
}

... 其它的一些 setXXX() 方法

// 生成最终的产品
public ComputerB build(){
return new ComputerB(this) ;
}
}
}

测试这个类

public class Test {
public static void main(String args[]){

// 不使用建造者模式
Computer computer = new Computer("主板","cpu","hd","电源","显卡"
,"鼠标","机箱","鼠标垫");
System.out.println("使用普通的构造方法组装电脑:"+computer.toString());

// 使用建造者模式
ComputerB computerB = new ComputerB.ComputerBuilder("主板","cpu","hd","电源","显卡")
.setMouse("鼠标").setMousePad("垫子").build() ;
System.out.println("使用建造者模式组装电脑:"+computerB.toString());
}
}